<?php
class MP4IphoneEncoder extends BaseEncoder {
	const VIDEO_TEMP_DIR = '/data/video_infrastructure/video/tmp';

	public function getFormatId() {
		return 2;
	}

	public function getFormat() {
			return 'm4v';
	}

	public function encode(array $data) {
		return $this->encodeMP4Iphone($data['video_files'], $data['output_file'], $data['width'], $data['height'], $data['video_bitrate'], $data['frame_rate'], $data['pixel_aspect_ratio'], $data['audio_bitrate'], $data['audio_channel'], $data['audio_sample_rate']);
	}

	protected function merge($video_list, $output_file) {
		$n = count($video_list);

		if ($n >= 1) {
				$video_list_string = implode(" -cat ", $video_list);
				$command = "/opt/gpac/bin/MP4Box -quiet -flat -inter 0 -unhint -no-sys -no-iod -add {$video_list_string} {$output_file}";
				exec($command, $command_output, $ret);

				return ($ret === 0);
		}

		return FALSE;
	}

	protected function hint($output_file){
		$command = "/opt/gpac/bin/MP4Box -hint {$output_file}";
		passthru($command, $ret);
		return ($ret === 0 );
	}


	public function encodeMP4Iphone($video_files, $output_file, $width, $height, $video_bitrate, $frame_rate, $pixel_aspect_ratio, $audio_bitrate, $audio_channel, $audio_sample_rate) {

		$time = time();
		$rand = rand(1, 1000000);
		$input_file = self::VIDEO_TEMP_DIR . "/merged-{$time}-{$rand}.mp4";
		$ret = self::merge($video_files, $input_file);

		if ($ret === FALSE) {
			error_log("ERROR: merge h264 failed");
			error_log("merge(" . implode(",", $video_files) . ", $input_file)");

			return FALSE;
		}

		$ret = $this->encodeM4V($input_file, $width, $height, $video_bitrate, $frame_rate, $audio_bitrate, $audio_channel, $audio_sample_rate, $output_file);
		if ($ret === FALSE) {
			error_log("ERROR: encode m4v failed");
			error_log("encodeM4V($input_file, $width, $height, $video_bitrate, $frame_rate, $audio_bitrate, $audio_channel, $audio_sample_rate, $output_file)");
			return FALSE;
		}

		$ret = $this->hint($output_file);
		if ($ret === FALSE) {
			error_log("ERROR: hint m4v failed");
			error_log("hint($output_file)");
			return FALSE;
		}

		# final cleanup
		unlink($input_file);
		
		return TRUE;
	}

	protected function encodeM4V($input_file, $width, $height, $video_bitrate, $frame_rate, $audio_bitrate, $audio_channel, $audio_sample_rate, $output_file) {
		$video_bitrate = $video_bitrate / 1000;
		$audio_bitrate = $audio_bitrate / 1000;
		
		$cmd = "/opt/ffmpeg/bin/ffmpeg -y -v 0 -i {$input_file} -s {$width}x{$height} -r {$frame_rate} -b {$video_bitrate}k -vcodec libx264 -ab {$audio_bitrate}k -ac {$audio_channel} -ar {$audio_sample_rate} -acodec libfaac {$output_file}";
		passthru($cmd, $ret);
		return ($ret === 0 );
	}
}

$encoder = new MP4IphoneEncoder();
$ret = EncoderFactory::getInstance()->register($encoder->getFormatId(), $encoder);
?>
